home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / gepackte_disketten / 1994 / 08_94_5.dms / 08_94_5.adf / term-4.0-Source.lha / termHotkeys.c < prev    next >
C/C++ Source or Header  |  1994-06-19  |  7KB  |  417 lines

  1. /*
  2. **    termHotkeys.c
  3. **
  4. **    Hotkey support routines.
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12. enum    {    CX_TERMSCREENTOFRONT,CX_BUFFERSCREENTOFRONT,CX_SKIPDIALENTRY,CX_ABORTAREXX };
  13.  
  14.     /* Asynchronous hotkey task. */
  15.  
  16. STATIC struct Process *CxProcess;
  17.  
  18.     /* Hotkey(STRPTR Code,struct MsgPort *Port,LONG ID):
  19.      *
  20.      *    A custom version of the amiga.lib supplied code.
  21.      */
  22.  
  23. STATIC CxObj * __regargs
  24. CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID)
  25. {
  26.     CxObj *Filter;
  27.  
  28.     if(Filter = CxFilter(Code))
  29.     {
  30.         CxObj *Sender;
  31.  
  32.         if(Sender = CxSender(Port,ID))
  33.         {
  34.             CxObj *Translator;
  35.  
  36.             AttachCxObj(Filter,Sender);
  37.  
  38.             if(Translator = CxTranslate(NULL))
  39.             {
  40.                 AttachCxObj(Filter,Translator);
  41.  
  42.                 if(!CxObjError(Filter))
  43.                     return(Filter);
  44.             }
  45.         }
  46.  
  47.         DeleteCxObjAll(Filter);
  48.     }
  49.  
  50.     return(NULL);
  51. }
  52.  
  53.     /* CreateBroker(struct MsgPort *CxPort):
  54.      *
  55.      *    Set up a CxObj commodity broker.
  56.      */
  57.  
  58. STATIC CxObj * __regargs
  59. CreateBroker(struct MsgPort *CxPort)
  60. {
  61.     CxObj *Broker;
  62.  
  63.         /* Set the commodity priority. */
  64.  
  65.     NewTermBroker . nb_Pri = Hotkeys . CommodityPriority;
  66.  
  67.         /* Create the broker. */
  68.  
  69.     if(Broker = CxBroker(&NewTermBroker,NULL))
  70.     {
  71.             /* Add the hotkeys. */
  72.  
  73.         AttachCxObj(Broker,CustomHotKey(Hotkeys . termScreenToFront,    CxPort,CX_TERMSCREENTOFRONT));
  74.         AttachCxObj(Broker,CustomHotKey(Hotkeys . BufferScreenToFront,    CxPort,CX_BUFFERSCREENTOFRONT));
  75.         AttachCxObj(Broker,CustomHotKey(Hotkeys . SkipDialEntry,    CxPort,CX_SKIPDIALENTRY));
  76.         AttachCxObj(Broker,CustomHotKey(Hotkeys . AbortARexx,        CxPort,CX_ABORTAREXX));
  77.  
  78.             /* Did an error show up? */
  79.  
  80.         if(!CxObjError(Broker))
  81.         {
  82.                 /* Broker has been added, now activate it. */
  83.  
  84.             ActivateCxObj(Broker,Hotkeys . HotkeysEnabled);
  85.  
  86.             return(Broker);
  87.         }
  88.  
  89.         DeleteCxObjAll(Broker);
  90.     }
  91.  
  92.     return(NULL);
  93. }
  94.  
  95.     /* TermCxServer():
  96.      *
  97.      *    Asynchronous hotkey server.
  98.      */
  99.  
  100. STATIC VOID __saveds
  101. TermCxServer(VOID)
  102. {
  103.     CxObj        *Broker;
  104.     struct MsgPort    *CxPort;
  105.     CxMsg        *Message;
  106.  
  107.         /* Create a reply port. */
  108.  
  109.     if(CxPort = CreateMsgPort())
  110.     {
  111.             /* Add the port to the public list. */
  112.  
  113.         CxPort -> mp_Node . ln_Name = NewTermBroker . nb_Name;
  114.  
  115.         AddPort(CxPort);
  116.  
  117.             /* Install the port. */
  118.  
  119.         NewTermBroker . nb_Port    = CxPort;
  120.  
  121.             /* Create the broker. */
  122.  
  123.         if(Broker = CreateBroker(CxPort))
  124.         {
  125.             ULONG    SignalSet;
  126.             BYTE    Terminated = FALSE;
  127.  
  128.                 /* Signal father task that we're done. */
  129.  
  130.             Signal(ThisProcess,SIG_HANDSHAKE);
  131.  
  132.                 /* Loop and loop... */
  133.  
  134.             while(!Terminated)
  135.             {
  136.                     /* Wait for some signal. */
  137.  
  138.                 SignalSet = Wait(SIG_KILL | SIG_RESET | PORTMASK(CxPort));
  139.  
  140.                     /* ^C aborts. */
  141.  
  142.                 if(SignalSet & SIG_KILL)
  143.                     Terminated = TRUE;
  144.  
  145.                     /* ^D removes the broker and
  146.                      * creates a new one.
  147.                      */
  148.  
  149.                 if(SignalSet & SIG_RESET)
  150.                 {
  151.                     DeleteCxObjAll(Broker);
  152.  
  153.                     Broker = CreateBroker(CxPort);
  154.                 }
  155.  
  156.                     /* A commodity message. */
  157.  
  158.                 if(SignalSet & PORTMASK(CxPort))
  159.                 {
  160.                     ULONG MessageType,MessageID;
  161.  
  162.                         /* Remove all messages. */
  163.  
  164.                     while(Message = (CxMsg *)GetMsg(CxPort))
  165.                     {
  166.                             /* Extract type and ID. */
  167.  
  168.                         MessageType    = CxMsgID(Message);
  169.                         MessageID    = CxMsgType(Message);
  170.  
  171.                         ReplyMsg((struct Message *)Message);
  172.  
  173.                             /* Take a look at the type... */
  174.  
  175.                         switch(MessageID)
  176.                         {
  177.                                 /* A hotkey was pressed. */
  178.  
  179.                             case CXM_IEVENT:
  180.  
  181.                                 switch(MessageType)
  182.                                 {
  183.                                     case CX_TERMSCREENTOFRONT:
  184.  
  185.                                         if(Window)
  186.                                             BumpWindow(TopWindow);
  187.                                         else
  188.                                             Signal(ThisProcess,SIGBREAKF_CTRL_F);
  189.  
  190.                                         break;
  191.  
  192.                                     case CX_BUFFERSCREENTOFRONT:
  193.  
  194.                                         LaunchBuffer();
  195.                                         break;
  196.  
  197.                                     case CX_SKIPDIALENTRY:
  198.  
  199.                                         Signal(ThisProcess,SIG_SKIP);
  200.                                         break;
  201.  
  202.                                     case CX_ABORTAREXX:
  203.  
  204.                                         if(InRexx)
  205.                                             Signal(ThisProcess,SIG_BREAK);
  206.  
  207.                                         break;
  208.                                 }
  209.  
  210.                                 break;
  211.  
  212.                                 /* An internal commodity command. */
  213.  
  214.                             case CXM_COMMAND:
  215.  
  216.                                 switch(MessageType)
  217.                                 {
  218.                                     case CXCMD_DISABLE:
  219.  
  220.                                         ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = FALSE);
  221.                                         break;
  222.  
  223.                                     case CXCMD_ENABLE:
  224.  
  225.                                         ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = TRUE);
  226.                                         break;
  227.                                 }
  228.  
  229.                                 break;
  230.                         }
  231.                     }
  232.                 }
  233.             }
  234.  
  235.                 /* Remove the broker. */
  236.  
  237.             DeleteCxObjAll(Broker);
  238.         }
  239.  
  240.             /* Remove the port from the public list. */
  241.  
  242.         RemPort(CxPort);
  243.  
  244.             /* Remove all pendig messages. */
  245.  
  246.         while(Message = (CxMsg *)GetMsg(CxPort))
  247.             ReplyMsg((struct Message *)Message);
  248.  
  249.             /* Delete the reply port. */
  250.  
  251.         DeleteMsgPort(CxPort);
  252.     }
  253.  
  254.     Forbid();
  255.  
  256.         /* Clear the task ID. */
  257.  
  258.     CxProcess = NULL;
  259.  
  260.         /* Signal father process that we're done. */
  261.  
  262.     Signal(ThisProcess,SIG_HANDSHAKE);
  263. }
  264.  
  265.     /* ShutdownCx():
  266.      *
  267.      *    Remove the hotkey task.
  268.      */
  269.  
  270. VOID
  271. ShutdownCx()
  272. {
  273.     if(CxProcess)
  274.     {
  275.         Forbid();
  276.  
  277.         Signal(CxProcess,SIG_KILL);
  278.  
  279.         ClrSignal(SIG_HANDSHAKE);
  280.  
  281.         Wait(SIG_HANDSHAKE);
  282.  
  283.         Permit();
  284.     }
  285. }
  286.  
  287.     /* SetupCx():
  288.      *
  289.      *    Create the hotkey task.
  290.      */
  291.  
  292. BYTE
  293. SetupCx()
  294. {
  295.         /* If the task is already running, tell it to
  296.          * update the hotkey settings.
  297.          */
  298.  
  299.     if(CxProcess)
  300.     {
  301.         Signal(CxProcess,SIG_RESET);
  302.  
  303.         return(TRUE);
  304.     }
  305.     else
  306.     {
  307.         Forbid();
  308.  
  309.         if(CxProcess = (struct Process *)CreateNewProcTags(
  310.             NP_Entry,    TermCxServer,
  311.             NP_Name,    "term Hotkey Process",
  312.             NP_Priority,    0,
  313.             NP_StackSize,    8192,
  314.             NP_WindowPtr,    -1,
  315.         TAG_END))
  316.         {
  317.             ClrSignal(SIG_HANDSHAKE);
  318.  
  319.             Wait(SIG_HANDSHAKE);
  320.         }
  321.  
  322.         Permit();
  323.  
  324.         if(CxProcess)
  325.             return(TRUE);
  326.     }
  327.  
  328.     return(FALSE);
  329. }
  330.  
  331.     /* LoadHotkeys(STRPTR Name,struct Hotkeys *Keys):
  332.      *
  333.      *    Load the hotkey settings from a file.
  334.      */
  335.  
  336. BYTE __regargs
  337. LoadHotkeys(STRPTR Name,struct Hotkeys *Keys)
  338. {
  339.     struct IFFHandle    *Handle;
  340.     BYTE             Success = FALSE;
  341.     struct StoredProperty    *Prop;
  342.     struct TermInfo        *TermInfo;
  343.     LONG             Error = 0;
  344.  
  345.     if(Handle = AllocIFF())
  346.     {
  347.         if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
  348.         {
  349.             InitIFFasDOS(Handle);
  350.  
  351.             if(!(Error = OpenIFF(Handle,IFFF_READ)))
  352.             {
  353.                 /* Collect version number ID if
  354.                  * available.
  355.                  */
  356.  
  357.                 if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
  358.                 {
  359.                     /* The following line tells iffparse to stop at the
  360.                      * very beginning of a `Type' chunk contained in a
  361.                      * `TERM' FORM chunk.
  362.                      */
  363.  
  364.                     if(!(Error = StopChunk(Handle,ID_TERM,ID_HOTK)))
  365.                     {
  366.                         /* Parse the file... */
  367.  
  368.                         if(!ParseIFF(Handle,IFFPARSE_SCAN))
  369.                         {
  370.                             /* Did we get a version ID? */
  371.  
  372.                             if(Prop = FindProp(Handle,ID_TERM,ID_VERS))
  373.                             {
  374.                                 TermInfo = (struct TermInfo *)Prop -> sp_Data;
  375.  
  376.                                 if((TermInfo -> Version < TermVersion) || (TermInfo -> Version == TermVersion && TermInfo -> Revision < TermRevision))
  377.                                 {
  378.                                     if(ReadChunkBytes(Handle,Keys,sizeof(struct HotkeysOld)) == sizeof(struct HotkeysOld))
  379.                                     {
  380.                                         strcpy(Keys -> AbortARexx,"lshift rshift escape");
  381.  
  382.                                         Success = TRUE;
  383.                                     }
  384.                                     else
  385.                                         Error = IoErr();
  386.                                 }
  387.                                 else
  388.                                 {
  389.                                     if(ReadChunkBytes(Handle,Keys,sizeof(struct Hotkeys)) == sizeof(struct Hotkeys))
  390.                                         Success = TRUE;
  391.                                     else
  392.                                         Error = IoErr();
  393.                                 }
  394.                             }
  395.                         }
  396.                     }
  397.                 }
  398.  
  399.                 CloseIFF(Handle);
  400.             }
  401.  
  402.             Close(Handle -> iff_Stream);
  403.         }
  404.         else
  405.             Error = IoErr();
  406.  
  407.         FreeIFF(Handle);
  408.     }
  409.     else
  410.         Error = ERR_NO_MEM;
  411.  
  412.     if(Error)
  413.         SetIoErr(Error);
  414.  
  415.     return(Success);
  416. }
  417.